<template>
  <el-dialog
    :model-value="visible"
    :title="dialogTitle"
    width="80%"
    :before-close="handleClose"
    append-to-body
    destroy-on-close
  >
    <el-row :gutter="20">
      <!-- 左侧部门树 -->
      <el-col :span="4" :xs="24">
        <div class="h-400px border border-gray-200 rounded p-2">
          <DeptTree @node-click="handleDeptNodeClick" />
        </div>
      </el-col>
      <el-col :span="20" :xs="24">
        <!-- 搜索 -->
        <el-form
          class="mb-4"
          :model="queryParams"
          ref="queryFormRef"
          :inline="true"
          label-width="80px"
        >
          <el-form-item label="用户名称" prop="username">
            <el-input
              v-model="queryParams.username"
              placeholder="请输入用户名称"
              clearable
              @keyup.enter="handleQuery"
              class="!w-180px"
            />
          </el-form-item>
          <el-form-item label="手机号码" prop="mobile">
            <el-input
              v-model="queryParams.mobile"
              placeholder="请输入手机号码"
              clearable
              @keyup.enter="handleQuery"
              class="!w-180px"
            />
          </el-form-item>
          <el-form-item label="状态" prop="status">
            <el-select
              v-model="queryParams.status"
              placeholder="请选择用户状态"
              clearable
              class="!w-180px"
            >
              <el-option
                v-for="dict in getIntDictOptions(DICT_TYPE.COMMON_STATUS)"
                :key="dict.value"
                :label="dict.label"
                :value="dict.value"
              />
            </el-select>
          </el-form-item>
          <el-form-item>
            <el-button @click="handleQuery"><Icon icon="ep:search" />搜索</el-button>
            <el-button @click="resetQuery"><Icon icon="ep:refresh" />重置</el-button>
          </el-form-item>
        </el-form>

        <!-- 已选择用户显示（多选模式） -->
        <div v-if="multiple && selectedUsers.length > 0" class="mb-4">
          <div class="text-sm text-gray-600 mb-2">已选择用户 ({{ selectedUsers.length }})</div>
          <div class="flex flex-wrap gap-2">
            <el-tag
              v-for="user in selectedUsers"
              :key="user.id"
              closable
              @close="removeSelectedUser(user.id)"
              type="primary"
            >
              {{ user.nickname }}({{ user.username }})
            </el-tag>
          </div>
        </div>

        <!-- 用户表格 -->
        <el-table
          ref="tableRef"
          v-loading="loading"
          :data="list"
          @selection-change="handleSelectionChange"
          :row-class-name="getRowClassName"
          height="400"
        >
          <!-- 多选列 -->
          <el-table-column
            v-if="multiple"
            type="selection"
            width="55"
            :selectable="checkSelectable"
          />
          <!-- 单选列 -->
          <el-table-column v-else width="55" align="center">
            <template #default="{ row }">
              <el-radio
                :model-value="selectedUserId"
                :label="row.id"
                @change="handleSingleSelect(row)"
              >
                &nbsp;
              </el-radio>
            </template>
          </el-table-column>

          <el-table-column label="用户编号" align="center" prop="id" width="80" />
          <el-table-column
            label="用户名"
            align="center"
            prop="username"
            :show-overflow-tooltip="true"
            width="120"
          />
          <el-table-column label="员工工号" align="center" prop="userCode" width="120" />
          <el-table-column
            label="员工姓名"
            align="center"
            prop="nickname"
            :show-overflow-tooltip="true"
            width="120"
          />
          <el-table-column
            label="部门"
            align="center"
            prop="deptName"
            :show-overflow-tooltip="true"
          />
          <el-table-column label="手机号码" align="center" prop="mobile" width="120" />
          <el-table-column label="状态" width="80">
            <template #default="scope">
              <el-tag :type="scope.row.status === 0 ? 'success' : 'danger'">
                {{ scope.row.status === 0 ? '正常' : '停用' }}
              </el-tag>
            </template>
          </el-table-column>
        </el-table>

        <!-- 分页 -->
        <div class="mt-4 flex justify-center">
          <el-pagination
            :current-page="queryParams.pageNo"
            :page-size="queryParams.pageSize"
            :total="total"
            :page-sizes="[10, 20, 50, 100]"
            layout="total, sizes, prev, pager, next, jumper"
            @size-change="handleSizeChange"
            @current-change="handleCurrentChange"
          />
        </div>
      </el-col>
    </el-row>

    <template #footer>
      <div class="dialog-footer">
        <el-button @click="handleClose">取消</el-button>
        <el-button type="primary" @click="handleConfirm" :disabled="!canConfirm">
          确定{{ multiple ? `(${selectedUsers.length})` : '' }}
        </el-button>
      </div>
    </template>
  </el-dialog>
</template>

<script lang="ts" setup>
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
import * as UserApi from '@/api/system/user'
import DeptTree from './DeptTree.vue'
import {  ref, reactive, computed, watch, nextTick } from 'vue'
defineOptions({ name: 'UserSelectDialog' })

// Props 定义
interface Props {
  /** 是否显示弹窗 */
  modelValue?: boolean
  /** 是否多选 */
  multiple?: boolean
  /** 已选择的用户ID（单选时为string，多选时为string[]） */
  selectedIds?: string | string[]
  /** 弹窗标题 */
  title?: string
  /** 是否可选择停用用户 */
  allowDisabled?: boolean
  /** 排除的用户ID列表 */
  excludeIds?: string[]
}

const props = withDefaults(defineProps<Props>(), {
  modelValue: false,
  multiple: false,
  selectedIds: undefined,
  title: '',
  allowDisabled: false,
  excludeIds: () => []
})

// Emits 定义
const emits = defineEmits(['update:modelValue', 'confirm'])

// 响应式数据
const visible = ref(false)
const loading = ref(false)
const total = ref(0)
const list = ref<UserApi.UserVO[]>([])
const selectedUsers = ref<UserApi.UserVO[]>([])
const selectedUserId = ref<string>('')
const tableRef = ref()

// 查询参数
const queryParams = reactive({
  pageNo: 1,
  pageSize: 10,
  username: undefined,
  mobile: undefined,
  status: undefined,
  deptId: undefined
})

const queryFormRef = ref()

// 计算属性
const dialogTitle = computed(() => {
  if (props.title) return props.title
  return props.multiple ? '选择用户（多选）' : '选择用户'
})

const canConfirm = computed(() => {
  return props.multiple ? selectedUsers.value.length > 0 : selectedUserId.value !== ''
})

// 监听弹窗显示状态
watch(() => props.modelValue, (newVal) => {
  visible.value = newVal
  if (newVal) {
    initializeSelection()
    getList()
  }
})

watch(visible, (newVal) => {
  emits('update:modelValue', newVal)
})

/** 初始化选择状态 */
const initializeSelection = async () => {
  if (!props.selectedIds) {
    selectedUsers.value = []
    selectedUserId.value = ''
    return
  }

  try {
    if (props.multiple) {
      const ids = Array.isArray(props.selectedIds) ? props.selectedIds : [props.selectedIds]
      if (ids.length > 0) {
        // 批量获取用户信息用于回显
        const users = await Promise.all(
          ids.map(async (id) => {
            try {
              return await UserApi.getUser(Number(id))
            } catch {
              return null
            }
          })
        )
        selectedUsers.value = users.filter(user => user !== null) as UserApi.UserVO[]
      }
    } else {
      selectedUserId.value = Array.isArray(props.selectedIds)
        ? props.selectedIds[0] || ''
        : props.selectedIds
    }
  } catch (error) {
    console.warn('初始化用户选择状态失败:', error)
  }
}

/** 查询用户列表 */
const getList = async () => {
  loading.value = true
  try {
    const data = await UserApi.getUserPage(queryParams)
    list.value = data.list
    total.value = data.total

    // 设置表格选中状态
    await nextTick()
    if (props.multiple && selectedUsers.value.length > 0) {
      const selectedIds = selectedUsers.value.map(u => u.id)
      list.value.forEach(row => {
        if (selectedIds.includes(row.id)) {
          tableRef.value?.toggleRowSelection(row, true)
        }
      })
    }
  } finally {
    loading.value = false
  }
}

/** 部门节点点击 */
const handleDeptNodeClick = (node: any) => {
  queryParams.deptId = node.id
  queryParams.pageNo = 1
  getList()
}

/** 搜索 */
const handleQuery = () => {
  queryParams.pageNo = 1
  getList()
}

/** 重置 */
const resetQuery = () => {
  queryFormRef.value?.resetFields()
  queryParams.deptId = undefined
  handleQuery()
}

/** 分页大小改变 */
const handleSizeChange = (size: number) => {
  queryParams.pageSize = size
  queryParams.pageNo = 1
  getList()
}

/** 当前页改变 */
const handleCurrentChange = (page: number) => {
  queryParams.pageNo = page
  getList()
}

/** 检查行是否可选择 */
const checkSelectable = (row: UserApi.UserVO) => {
  // 排除指定的用户ID
  if (props.excludeIds.includes(String(row.id))) {
    return false
  }
  // 如果不允许选择停用用户
  if (!props.allowDisabled && row.status !== 0) {
    return false
  }
  return true
}

/** 获取行样式类名 */
const getRowClassName = ({ row }: { row: UserApi.UserVO }) => {
  const isSelected = props.multiple
    ? selectedUsers.value.some(u => u.id === row.id)
    : selectedUserId.value === String(row.id)

  return isSelected ? 'selected-row' : ''
}

/** 行点击事件 */
const handleRowClick = (row: UserApi.UserVO) => {
  if (!checkSelectable(row)) return

  if (props.multiple) {
    const isSelected = selectedUsers.value.some(u => u.id === row.id)
    if (isSelected) {
      removeSelectedUser(row.id)
    } else {
      selectedUsers.value.push(row)
    }
    // 更新表格选择状态
    tableRef.value?.toggleRowSelection(row, !isSelected)
  } else {
    selectedUserId.value = String(row.id)
  }
}

/** 单选处理 */
const handleSingleSelect = (row: UserApi.UserVO) => {
  if (!checkSelectable(row)) return
  selectedUserId.value = String(row.id)
}

/** 多选变化处理 */
const handleSelectionChange = (selection: UserApi.UserVO[]) => {
  // selection 只包含当前页已勾选的用户
  // 1. 先合并当前页已勾选到 selectedUsers
  const selectionIds = selection.map(u => u.id)
  // 2. 移除 selectedUsers 中当前页未勾选的用户
  const currentPageIds = list.value.map(u => u.id)
  // 3. 先保留非当前页的已选
  let newSelected = selectedUsers.value.filter(u => !currentPageIds.includes(u.id))
  // 4. 再加上当前页已勾选
  newSelected = newSelected.concat(selection)
  // 5. 去重
  const map = new Map<number, UserApi.UserVO>()
  newSelected.forEach(u => map.set(u.id, u))
  selectedUsers.value = Array.from(map.values())
}

/** 移除已选择的用户 */
const removeSelectedUser = (userId: number) => {
  const index = selectedUsers.value.findIndex(u => u.id === userId)
  if (index > -1) {
    selectedUsers.value.splice(index, 1)
  }
  // 更新表格选择状态
  const row = list.value.find(r => r.id === userId)
  if (row) {
    tableRef.value?.toggleRowSelection(row, false)
  }
}

/** 确认选择 */
const handleConfirm = () => {
  if (props.multiple) {
    const ids = selectedUsers.value.map(u => String(u.id))
    emits('confirm', selectedUsers.value, ids)
  } else {
    const selectedUser = list.value.find(u => String(u.id) === selectedUserId.value)
    if (selectedUser) {
      emits('confirm', selectedUser, selectedUserId.value)
    }
  }
  handleClose()
}

/** 关闭弹窗 */
const handleClose = () => {
  visible.value = false
}

// 暴露方法给父组件
defineExpose({
  open: () => {
    visible.value = true
  },
  close: () => {
    visible.value = false
  }
})

watch(() => visible.value, (val) => {
  if (val === false) {
    selectedUsers.value = []
    selectedUserId.value = ''
  }
})
</script>

<style scoped>
:deep(.selected-row) {
  background-color: #f0f9ff !important;
}

:deep(.selected-row:hover) {
  background-color: #e0f2fe !important;
}

:deep(.el-table__row) {
  cursor: pointer;
}

:deep(.el-table__row:hover) {
  background-color: #f5f7fa;
}
</style>
